import { _decorator, assetManager, Component, Node, sp, Texture2D, tween, UIOpacity, type ImageAsset, type EventTarget } from 'cc'
import { Logger, ServiceLocator } from '../utils'
import { FrameEvents, ServiceName } from '../../enum'
import type { Chapter } from '../store'
const { ccclass, property } = _decorator

@ccclass('SpineFrame')
export class SpineFrame extends Component {

    @property(Node)
    spine: Node

    #services = ServiceLocator

    get spineComponent() {
        return this.spine.getComponent(sp.Skeleton)
    }

    get opacity() {
        return this.spine.getComponent(UIOpacity)
    }

    get chapter(): Chapter {
        return this.#services.get(ServiceName.Chapter)
    }

    get events(): EventTarget {
        return this.#services.get(ServiceName.Event)
    }

    #log = new Logger('特效帧');

    start() {

    }

    fadeIn() {
        return new Promise((resolve) => tween(this.opacity)
            .to(0.5, { opacity: 255 }, { easing: 'fade' })
            .call(resolve).start())
    }

    fadeOut() {
        return new Promise((resolve) => tween(this.opacity)
            .to(0.5, { opacity: 0 }, { easing: 'fade' })
            .call(resolve).start())
    }

    run(content: LDContent.SpineContent) {
        this.#log.debug('处理特效帧 %o', content)
        const atlas = this.chapter.getResource(content.spine.atlas.resourceId)
        const json = this.chapter.getResource(content.spine.json.resourceId)
        const png = this.chapter.getResource(content.spine.png.resourceId)
        assetManager.loadAny([{
            url: atlas.ossUrl,
            ext: '.txt'
        }, {
            url: json.ossUrl,
            ext: '.txt'
        }], (err, assets) => {
            assetManager.loadRemote<ImageAsset>(png.ossUrl, async (err, img) => {
                if (this.opacity.opacity) {
                    await this.fadeOut()
                }

                const texture = new Texture2D()
                texture.image = img
                const skData = new sp.SkeletonData()
                skData.skeletonJson = assets[1]
                skData.atlasText = assets[0]
                skData.textures = [texture]
                skData.textureNames = [png.name]
                this.spineComponent.skeletonData = skData
                this.spineComponent.animation = 'animation'
                this.spineComponent.loop = content.loop
                this.spineComponent.timeScale = content.timeScale ?? 1
                await this.fadeIn()
                this.events.emit(FrameEvents.frameLock, false)
                this.events.emit(FrameEvents.stepNext)
            })
        })

    }
}


